package com.neunn.demo.sales.controller;

import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.neunn.demo.sales.service.ProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.LinkedHashMap;
import java.util.Map;

/**
 * @author anyuan
 * @date 2018-12-26 11:39
 */
@RestController
public class SalesController {

    @Autowired
    private RestTemplate restTemplate;

    @Value("${server.port}")
    private Integer port;

    @RequestMapping(path = "/health")
    public String health() {
        return "I'm healthy --this message is from port [" + port + "]";
    }

    /**
     * fallbackMethod指定出现异常时的处理方法
     * 同时测试多个rest节点之间的互相调用
     *
     * @param accountName
     * @param productName
     * @param buyCount
     * @return
     */
    @HystrixCommand(fallbackMethod = "buyError")
    @RequestMapping(method = RequestMethod.POST, path = "/buy")
    public Map<String, Object> buyProduct(@RequestParam(name = "account") String accountName,
                                          @RequestParam(name = "product") String productName,
                                          @RequestParam(name = "buyCount") Integer buyCount) {
        Map<String, Object> returnMap = new LinkedHashMap<>(2);
        String returnMessage = null;
        Double balance = restTemplate.getForObject("http://account-service/balance?accountName=" + accountName, Double.class);
        System.out.println(balance);
        Integer margin = restTemplate.getForObject("http://product-service/margin?productName=" + productName, Integer.class);
        System.out.println(margin);
        if (margin != null && margin >= buyCount) {
            /*若余货充足*/
            Double price = restTemplate.getForObject("http://product-service/price?productName=" + productName, Double.class);
            System.out.println(price);
            if (balance != null && price != null && balance >= buyCount * price) {
                /*若余额充足*/
                MultiValueMap<String, Object> productRequest = new LinkedMultiValueMap<>();
                productRequest.add("productName", productName);
                productRequest.add("number", buyCount);
                Integer marginLeft = restTemplate.postForObject("http://product-service/marginMinus", productRequest, Integer.class);
                System.out.println(marginLeft);
                MultiValueMap<String, Object> accountRequest = new LinkedMultiValueMap<>();
                accountRequest.add("accountName", accountName);
                accountRequest.add("money", buyCount * price);
                Double balanceLeft = restTemplate.postForObject("http://account-service/spend", accountRequest, Double.class);
                System.out.println(balanceLeft);
                returnMessage = "购买完成，[" + productName + "]产品还剩下[" + marginLeft + "]个，账户[" + accountName + "]的余额还剩下[" + balanceLeft + "]。";
                System.out.println(returnMessage);
            }
        }
        returnMap.put("status", "succeed");
        returnMap.put("message", returnMessage);
        return returnMap;
    }

    /**
     * 降级(异常)时使用的方法
     *
     * @param accountName
     * @param productName
     * @param buyCount
     * @return
     */
    public Map<String, Object> buyError(String accountName,
                                        String productName,
                                        Integer buyCount) {
        Map<String, Object> returnMap = new LinkedHashMap<>(2);
        returnMap.put("status", "failed");
        returnMap.put("message", "unkonwn error occurs");
        return returnMap;
    }


    @Autowired
    private ProductService productService;

    @RequestMapping(method = RequestMethod.GET, path = "/marginFromProductService")
    public Integer marginFromProductService(@RequestParam(name = "productName") String productName) {
        System.out.println("通过controller调用service调用外部(product-service)的rest接口");
        return productService.marginFromProductService(productName);
    }

    @RequestMapping(method = RequestMethod.GET, path = "/healthFromProductService")
    public String healthFromProductService() {
        System.out.println("通过controller调用service调用外部(product-service)的rest接口");
        return productService.healthFromProductService();
    }
}
